//
//  HomeViewModel.swift
//  DaRings
//
//  Created by 尹琼 on 2022/10/28.
//

import UIKit
import MYModule
import RxCocoa
import RxSwift
import SwiftDate
import CRPSmartRing

public class HomeViewModel: NSObject, ViewModelType {
    
    public var inPut: Input
    public var outPut: Output
    
    fileprivate var isBatterycharging: Bool
    
    public struct Input {
        public let viewWillAppear:ControlEvent<Bool>
        public let headerRefresh:ControlEvent<Void>?
        

    }
    
    public struct Output {
        
        public let dateObserver = BehaviorRelay<Date>(value: Date())
       
        public let divice = BehaviorRelay<HomeDeviceViewModel?>(value: nil)
        public let activity = BehaviorRelay<HomeActivityViewModel?>(value: nil)
        public let workoutsRecords = BehaviorRelay<HomeWorkoutsRecordViewModel?>(value: nil)
        public let sleep = BehaviorRelay<HomeSleepViewModel?>(value: nil)
        public let heartRate = BehaviorRelay<HomeHeartRateViewModel?>(value: nil)
        public let bloodOxygen = BehaviorRelay<HomeBloodOxygenViewModel?>(value: nil)
        public let HRV = BehaviorRelay<HomeHRVViewModel?>(value: nil)
        public let stress = BehaviorRelay<HomeStressViewModel?>(value: nil)
        
        public let dataSource = BehaviorRelay<[HomeSection]>(value: [])
        
    }
    
    
    public required init(input: Input) {
        
        self.inPut = input
        self.outPut = Output()
        
        self.isBatterycharging = BluetoothManager.shared.isBatterycharging

        super.init()
        
        NotificationCenter.default.rx.notification(.kUpdateUINotification).take(until: self.rx.deallocated).subscribe(onNext: {[weak self] in
            
                self?.notifactionAction(noti: $0)
            
        }).disposed(by: rx.disposeBag)
        
        // 点测状态更改刷新所有点测按钮
        NotificationCenter.default.rx.notification(.kReceiveMeasuringNotification).take(until: self.rx.deallocated).subscribe(onNext: {[weak self] _ in
            
            self?.reloadData()
            
        }).disposed(by: rx.disposeBag)
        
        
    }
    

    @objc public func notifactionAction(noti: Notification) {
        
        guard let dict = noti.userInfo as? [String: Any], let type = dict["type"] as? NotifactionType else { return }
        
        let date = outPut.dateObserver.value
        
        switch type {
            
        case .deviceState:
            
            reloadData()
            
            break
            
        case .bluetoothState:
            
            reloadData()
            break
            
        case .activity:
            
            let viewModel = outPut.activity.value
            viewModel?.dateReplay.accept(date)
            outPut.activity.accept(viewModel)
            break
            
        case .sleep:
            
            let viewModel = outPut.sleep.value
            viewModel?.dateReplay.accept(date)
            outPut.sleep.accept(viewModel)
            
        case .heartRate:
            
            let viewModel = outPut.heartRate.value
            viewModel?.dateReplay.accept(date)
            outPut.heartRate.accept(viewModel)
            break
        case .singleHeartRate:
            
            guard let viewModel = outPut.heartRate.value else {
                return
            }
            
            // 更新测量后显示
            viewModel.measuredData()
            
            outPut.heartRate.accept(viewModel)

            break
        
        case .singleHRV:
            
            // 更新单次测量的UI
            guard let viewModel = outPut.HRV.value else {
                return
            }
            
            // 更新测量后显示
            viewModel.measuredData()
            outPut.HRV.accept(viewModel)
            
            break
            
        case .singleStress:
            // 更新单次测量的UI
            guard let viewModel = outPut.stress.value else {
                return
            }
            
            // 更新测量后显示
            viewModel.measuredData()
            outPut.stress.accept(viewModel)
            
            break
            
        case .singleBloodOxygen:
            
            // 更新单次测量的UI
            guard let viewModel = outPut.bloodOxygen.value else {
                return
            }
            // 更新测量后显示
            viewModel.measuredData()
            outPut.bloodOxygen.accept(viewModel)
           
        
            break
        case .upgrede:
            
            break
        case .sportList:
            
            let viewModel = outPut.workoutsRecords.value
           
            viewModel?.dateReplay.accept(date)
            outPut.workoutsRecords.accept(viewModel)
            
            break
            
//        case .sportState:
//
//            let viewModel = outPut.workoutsRecords.value
//            viewModel?.dateReplay.accept(date)
//            outPut.workoutsRecords.accept(viewModel)
//
//
//
//            break
            
        case .battery:
            
            /// 充电/不充电交接时候，刷新点测按钮状态
            if self.isBatterycharging != BluetoothManager.shared.isBatterycharging {
                
                reloadData()
        
            }
            
            self.isBatterycharging = BluetoothManager.shared.isBatterycharging
        
           break
            
        default:
            break
        }
        
    }
    

    public func transform(input: Input) -> Output {
        
        let outPut = self.outPut
        
        let date = Date()
        let divice = HomeDeviceViewModel()
        let activity = HomeActivityViewModel(date: date)
        let workOuts = HomeWorkoutsRecordViewModel(date: date)
        let sleep = HomeSleepViewModel(date: date)
        let heartRate = HomeHeartRateViewModel(date: date)
        let bloodOxyen = HomeBloodOxygenViewModel(date: date)
        let HRV = HomeHRVViewModel(date: date)
        let stress = HomeStressViewModel(date: date)
        
        outPut.divice.accept(divice)
        outPut.activity.accept(activity)
        outPut.workoutsRecords.accept(workOuts)
        outPut.sleep.accept(sleep)
        outPut.heartRate.accept(heartRate)
        outPut.bloodOxygen.accept(bloodOxyen)
        outPut.HRV.accept(HRV)
        outPut.stress.accept(stress)
        
        input.viewWillAppear.asObservable().subscribe(onNext: {[weak self] _ in
            
            self?.reloadData()
            
        }).disposed(by: rx.disposeBag)
        
        input.headerRefresh?.subscribe(onNext: {
            
            // 下拉刷新，指令更新数据
            BluetoothResponder.shared.updateTodayDatas()
            
        }).disposed(by: rx.disposeBag)
        
        // 刷新UI
        activity.reloadDataSubject.map {
            $0 as! HomeActivityViewModel
        }.bind(to: outPut.activity).disposed(by: rx.disposeBag)
        
        workOuts.reloadDataSubject.map {
            $0 as! HomeWorkoutsRecordViewModel
        }.bind(to: outPut.workoutsRecords).disposed(by: rx.disposeBag)
        
        sleep.reloadDataSubject.map {
            $0 as! HomeSleepViewModel
        }.bind(to: outPut.sleep).disposed(by: rx.disposeBag)
        
        heartRate.reloadDataSubject.map {
            $0 as! HomeHeartRateViewModel
        }.bind(to: outPut.heartRate).disposed(by: rx.disposeBag)
        
        bloodOxyen.reloadDataSubject.map {
            $0 as! HomeBloodOxygenViewModel
        }.bind(to: outPut.bloodOxygen).disposed(by: rx.disposeBag)
        
        HRV.reloadDataSubject.map {
            $0 as! HomeHRVViewModel
        }.bind(to: outPut.HRV).disposed(by: rx.disposeBag)
        
        stress.reloadDataSubject.map {
            $0 as! HomeStressViewModel
        }.bind(to: outPut.stress).disposed(by: rx.disposeBag)
        

        /// 日期更新刷新数据
        outPut.dateObserver.bind(to: activity.dateReplay).disposed(by: rx.disposeBag)
        outPut.dateObserver.bind(to: workOuts.dateReplay).disposed(by: rx.disposeBag)
        outPut.dateObserver.bind(to: sleep.dateReplay).disposed(by: rx.disposeBag)
        outPut.dateObserver.bind(to: heartRate.dateReplay).disposed(by: rx.disposeBag)
        outPut.dateObserver.bind(to: bloodOxyen.dateReplay).disposed(by: rx.disposeBag)
        outPut.dateObserver.bind(to: HRV.dateReplay).disposed(by: rx.disposeBag)
        outPut.dateObserver.bind(to: stress.dateReplay).disposed(by: rx.disposeBag)
    
        let dataSource = BehaviorRelay.combineLatest(outPut.divice,
                                                  outPut.activity,
                                                  outPut.workoutsRecords,
                                                  outPut.sleep,
                                                  outPut.heartRate,
                                                  outPut.bloodOxygen,
                                                  outPut.HRV,
                                                  outPut.stress).share()
        
       
        dataSource.map {
            
            // 默认全部显示
            var array = [
                $0.0,
                $0.1,
                $0.2,
                $0.3,
                $0.4,
                $0.5,
                $0.6,
                $0.7
            ]
            
          
            // 已经绑定
            if $0.0?.addDeviceRelay.value == true {

                if array.contains($0.0) {
                    // 不显示添加设备
                    array.removeFirst()
                }
                
            } else {
                
                // 是否绑定
                if DeviceInfo.current().isBind {
                    if array.contains($0.0) {
                        // 不显示添加设备
                        array.removeFirst()
                    }
                  
                } else {
                    
                    if !array.contains($0.0) {
                        // 显示添加设备
                        array.insert($0.0, at: 0)
                    }
                }
            }
            
//            print(array)
            
            let homeBaseViewModels =  array.compactMap { $0 }.map {
                
                HomeSection(hearder: "", items: [$0])
                
            }
            
            return homeBaseViewModels
            
        }.bind(to: outPut.dataSource).disposed(by: rx.disposeBag)
        
       
        return outPut
        
        
    }
    
    
    public func reloadData() {
        let date = Date()
        let oldDay = outPut.dateObserver.value.day
        let day = date.day
        
        if oldDay != day {
            // 日期更新，指令更新数据
            BluetoothResponder.shared.updateTodayDatas()
            
        } 
        
        outPut.dateObserver.accept(date)
       
    }
    
   
    
    
    
}
